package com.example.healthapp;



import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

import com.example.healthapp.ble.BLEManager;
import com.example.healthapp.ble.OnBleConnectListener;
import com.example.healthapp.ble.OnDeviceSearchListener;
import com.example.healthapp.permission.PermissionListener;
import com.example.healthapp.permission.PermissionRequest;
import com.example.healthapp.util.TypeConversion;

import com.example.healthapp.utils.InterfaceTool;

/**
 * BLE开发
 */
@RequiresApi(api = Build.VERSION_CODES.S)
public class MainActivitys extends AppCompatActivity implements View.OnClickListener {

    // 蓝牙服务 UUIDs 和权限常量
    public static final String SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
    public static final String READ_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
    public static final String WRITE_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";

    private final String[] requestPermissionArray = new String[]{
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    };

    // 设备连接状态常量
    private static final int CONNECT_SUCCESS = 0x01;
    private static final int CONNECT_FAILURE = 0x02;
    private static final int DISCONNECT_SUCCESS = 0x03;
    private static final int SEND_SUCCESS = 0x04;
    private static final int SEND_FAILURE = 0x05;
    private static final int RECEIVE_SUCCESS = 0x06;
    private static final int RECEIVE_FAILURE = 0x07;
    private static final int START_DISCOVERY = 0x08;
    private static final int STOP_DISCOVERY = 0x09;
    private static final int DISCOVERY_DEVICE = 0x0A;
    private static final int DISCOVERY_OUT_TIME = 0x0B;
    private static final int SELECT_DEVICE = 0x0C;
    private static final int BT_OPENED = 0x0D;
    private static final int BT_CLOSED = 0x0E;

    private Button btSearch, btConnect, btDisconnect, btSend;
    private TextView tvCurConState, tvName, tvAddress, tvSendResult, tvReceive,receiveData;
    private EditText etSendMsg;
    private ListView lvDevices;
    //    private LinearLayout llDeviceList, llDataSendReceive;
    private LVDevicesAdapter lvDevicesAdapter;
    private final String TAG = "MainActivitys";
    private Context mContext;
    private BLEManager bleManager;
    private BLEBroadcastReceiver bleBroadcastReceiver;
    private BluetoothDevice curBluetoothDevice;
    private boolean curConnState = false;  // 当前连接状态

    private static final int REQUEST_PERMISSION_CODE = 1;

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case START_DISCOVERY:
                    Log.d(TAG, "开始搜索设备...");
                    break;
                case STOP_DISCOVERY:
                    Log.d(TAG, "停止搜索设备...");
                    break;
                case DISCOVERY_DEVICE:
                    BLEDevice bleDevice = (BLEDevice) msg.obj;
                    lvDevicesAdapter.addDevice(bleDevice);
                    break;
                case SELECT_DEVICE:
                    BluetoothDevice bluetoothDevice = (BluetoothDevice) msg.obj;
                    if (ActivityCompat.checkSelfPermission(MainActivitys.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        return;
                    }
                    tvName.setText(bluetoothDevice.getName());
                    tvAddress.setText(bluetoothDevice.getAddress());
                    curBluetoothDevice = bluetoothDevice;
                    break;
                case CONNECT_FAILURE:
                    tvCurConState.setText("连接失败");
                    curConnState = false;
                    break;
                case CONNECT_SUCCESS:
                    tvCurConState.setText("连接成功");
                    curConnState = true;
//                    llDataSendReceive.setVisibility(View.VISIBLE);
//                    llDeviceList.setVisibility(View.GONE);
                    break;
                case DISCONNECT_SUCCESS:
                    tvCurConState.setText("断开成功");
                    curConnState = false;
                    break;
                case SEND_FAILURE:
                    byte[] sendBufFail = (byte[]) msg.obj;
                    tvSendResult.setText("发送数据失败，长度" + sendBufFail.length);
                    break;
                case SEND_SUCCESS:
                    byte[] sendBufSuc = (byte[]) msg.obj;
                    tvSendResult.setText("发送数据成功，长度" + sendBufSuc.length);
                    break;
                case RECEIVE_FAILURE:
                    String receiveError = (String) msg.obj;
                    tvReceive.setText(receiveError);
                    break;
                case RECEIVE_SUCCESS:
                    byte[] recBufSuc = (byte[]) msg.obj;
                    tvReceive.setText("接收数据成功，长度" + recBufSuc.length);
                    break;
                case BT_CLOSED:
                    Log.d(TAG, "系统蓝牙已关闭");
                    break;
                case BT_OPENED:
                    Log.d(TAG, "系统蓝牙已打开");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_ble);

        mContext = MainActivitys.this;

        // 初始化视图
        initView();
        // 初始化监听器
        initListeners();
        // 初始化数据
        initData();
        // 注册蓝牙广播接收器
        initBLEBroadcastReceiver();
        // 初始化权限
        initPermissions();
    }

    private void initView() {
        btSearch = findViewById(R.id.bt_search);
        tvCurConState = findViewById(R.id.tv_cur_con_state);
        btConnect = findViewById(R.id.bt_connect);
        btDisconnect = findViewById(R.id.bt_disconnect);
        tvName = findViewById(R.id.tv_name);
        tvAddress = findViewById(R.id.tv_address);
        etSendMsg = findViewById(R.id.et_send_msg);
        btSend = findViewById(R.id.bt_to_send);
        tvSendResult = findViewById(R.id.tv_send_result);
        tvReceive = findViewById(R.id.tv_receive_result);
//        llDeviceList = findViewById(R.id.ll_device_list);
//        llDataSendReceive = findViewById(R.id.ll_data_send_receive);
        lvDevices = findViewById(R.id.lv_devices);
        // receiveData = findViewById(R.id.tv_receive_results);
    }

    private void initListeners() {
        btSearch.setOnClickListener(this);
        btConnect.setOnClickListener(this);
        btDisconnect.setOnClickListener(this);
        btSend.setOnClickListener(this);

        lvDevices.setOnItemClickListener((adapterView, view, i, l) -> {
            BLEDevice bleDevice = (BLEDevice) lvDevicesAdapter.getItem(i);
            BluetoothDevice bluetoothDevice = bleDevice.getBluetoothDevice();
            if (bleManager != null) {
                bleManager.stopDiscoveryDevice();
            }
            Message message = new Message();
            message.what = SELECT_DEVICE;
            message.obj = bluetoothDevice;
            mHandler.sendMessage(message);
        });
    }

    private void initData() {
        lvDevicesAdapter = new LVDevicesAdapter(MainActivitys.this);
        lvDevices.setAdapter(lvDevicesAdapter);

        bleManager = new BLEManager();
        if (!bleManager.initBle(mContext)) {
            Toast.makeText(mContext, "设备不支持BLE", Toast.LENGTH_SHORT).show();
        } else {
            if (!bleManager.isEnable()) {
                bleManager.openBluetooth(mContext, false);
            }
        }
    }

    private void initBLEBroadcastReceiver() {
        bleBroadcastReceiver = new BLEBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(bleBroadcastReceiver, intentFilter);
    }

    private void initPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PermissionRequest permissionRequest = new PermissionRequest();
            permissionRequest.requestRuntimePermission(MainActivitys.this, requestPermissionArray, new PermissionListener() {
                @Override
                public void onGranted() {
                    Log.d(TAG, "所有权限已授予");
                }

                @Override
                public void onDenied(List<String> deniedPermissions) {
                    for (String deniedPermission : deniedPermissions) {
                        Log.e(TAG, "被拒绝权限：" + deniedPermission);
                    }
                }
            });
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(bleBroadcastReceiver);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.bt_search) {
//            llDataSendReceive.setVisibility(View.GONE);
//            llDeviceList.setVisibility(View.VISIBLE);
            searchBtDevice();
        } else if (view.getId() == R.id.bt_connect) {
            if (!curConnState) {
                if (bleManager != null) {
                    bleManager.connectBleDevice(mContext, curBluetoothDevice, 15000, SERVICE_UUID, READ_UUID, WRITE_UUID, onBleConnectListener);
                }
            } else {
                Toast.makeText(this, "当前设备已连接", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.bt_disconnect) {
            if (curConnState) {
                if (bleManager != null) {
                    bleManager.disConnectDevice();
                }
            } else {
                Toast.makeText(this, "当前设备未连接", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.bt_to_send) {
            if (curConnState) {
                String sendMsg = etSendMsg.getText().toString();
                if (sendMsg.isEmpty()) {
                    Toast.makeText(this, "发送数据为空", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (bleManager != null) {
                    bleManager.sendMessage(sendMsg);  // 发送16进制数据
                }
            } else {
                Toast.makeText(this, "请先连接设备", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void searchBtDevice() {
        if (bleManager == null) {
            return;
        }
        if (bleManager.isDiscovery()) {
            bleManager.stopDiscoveryDevice();
        }
        if (lvDevicesAdapter != null) {
            lvDevicesAdapter.clear();
        }
        bleManager.startDiscoveryDevice(onDeviceSearchListener, 15000);
    }

    private OnDeviceSearchListener onDeviceSearchListener = new OnDeviceSearchListener() {
        @Override
        public void onDeviceFound(BLEDevice bleDevice) {
            Message message = new Message();
            message.what = DISCOVERY_DEVICE;
            message.obj = bleDevice;
            mHandler.sendMessage(message);
        }

        @Override
        public void onDiscoveryOutTime() {
            Message message = new Message();
            message.what = DISCOVERY_OUT_TIME;
            mHandler.sendMessage(message);
        }
    };

    // BLE 连接回调
    private OnBleConnectListener onBleConnectListener = new OnBleConnectListener() {
        @Override
        public void onConnecting(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice) {
        }

        @Override
        public void onConnectSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
            Message message = new Message();
            message.what = CONNECT_SUCCESS;
            mHandler.sendMessage(message);
        }

        @Override
        public void onConnectFailure(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, String exception, int status) {
            Message message = new Message();
            message.what = CONNECT_FAILURE;
            mHandler.sendMessage(message);
        }

        @Override
        public void onDisConnecting(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice) {
        }

        @Override
        public void onDisConnectSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
            Message message = new Message();
            message.what = DISCONNECT_SUCCESS;
            mHandler.sendMessage(message);
        }

        @Override
        public void onServiceDiscoverySucceed(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, int status) {
            Message message = new Message();
            message.what = CONNECT_SUCCESS;
            mHandler.sendMessage(message);
        }

        @Override
        public void onServiceDiscoveryFailed(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, String failMsg) {
            Message message = new Message();
            message.what = CONNECT_FAILURE;
            mHandler.sendMessage(message);
        }

        @Override
        public void onReceiveMessage(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, BluetoothGattCharacteristic characteristic, byte[] msg) {
            Message message = new Message();
            message.what = RECEIVE_SUCCESS;
            message.obj = msg;
            mHandler.sendMessage(message);
        }

        @Override
        public void onReceiveError(String errorMsg) {
            Message message = new Message();
            message.what = RECEIVE_FAILURE;
            mHandler.sendMessage(message);
        }

        @Override
        public void onWriteSuccess(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, byte[] msg) {
            Message message = new Message();
            message.what = SEND_SUCCESS;
            message.obj = msg;
            mHandler.sendMessage(message);
        }

        @Override
        public void onWriteFailure(BluetoothGatt bluetoothGatt, BluetoothDevice bluetoothDevice, byte[] msg, String errorMsg) {
            Message message = new Message();
            message.what = SEND_FAILURE;
            message.obj = msg;
            mHandler.sendMessage(message);
        }

        @Override
        public void onReadRssi(BluetoothGatt bluetoothGatt, int Rssi, int status) {
        }

        @Override
        public void onMTUSetSuccess(String successMTU, int newMtu) {
        }

        @Override
        public void onMTUSetFailure(String failMTU) {
        }
    };

    /**
     * 蓝牙广播接收器
     */
    private class BLEBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                Message message = new Message();
                message.what = START_DISCOVERY;
                mHandler.sendMessage(message);
            } else if (TextUtils.equals(action, BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                Message message = new Message();
                message.what = STOP_DISCOVERY;
                mHandler.sendMessage(message);
            } else if (TextUtils.equals(action, BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                if (state == BluetoothAdapter.STATE_OFF) {
                    Message message = new Message();
                    message.what = BT_CLOSED;
                    mHandler.sendMessage(message);
                } else if (state == BluetoothAdapter.STATE_ON) {
                    Message message = new Message();
                    message.what = BT_OPENED;
                    mHandler.sendMessage(message);
                }
            }
        }
    }
}

